package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.common.PageResult;
import com.zhentao.entity.DynamicFavorites;
import com.zhentao.entity.DynamicLikes;
import com.zhentao.entity.UserDynamics;
import com.zhentao.mapper.DynamicFavoritesMapper;
import com.zhentao.mapper.DynamicLikesMapper;
import com.zhentao.mapper.UserDynamicsMapper;
import com.zhentao.service.InteractionService;
import com.zhentao.vo.DynamicVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class InteractionServiceImpl implements InteractionService {

    @Autowired
    private DynamicLikesMapper likesMapper;
    @Autowired
    private DynamicFavoritesMapper favoritesMapper;
    @Autowired
    private UserDynamicsMapper userDynamicsMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String LIKE_COUNT_KEY = "dynamic:like:";      // dynamic:like:{dynamicId}
    private static final String FAVORITE_COUNT_KEY = "dynamic:favorite:"; // dynamic:favorite:{dynamicId}

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void like(Integer userId, Integer dynamicId) {
        // 幂等：DB唯一索引限制（uk_dynamic_user）
        DynamicLikes like = new DynamicLikes();
        like.setUserId(userId);
        like.setDynamicId(dynamicId);
        like.setCreatedAt(LocalDateTime.now());
        try {
            likesMapper.insert(like);
            // 立即增加缓存计数（Redis不可用时忽略，不影响主流程）
            incrementCacheSafely(LIKE_COUNT_KEY + dynamicId, 1);
            // 可选：同步主表统计（+1）
            userDynamicsMapper.update(null,
                    new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<UserDynamics>()
                            .eq("dynamic_id", dynamicId)
                            .setSql("like_count = like_count + 1"));
        } catch (DuplicateKeyException ignore) {
            // 已点赞视为成功
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unlike(Integer userId, Integer dynamicId) {
        likesMapper.delete(new QueryWrapper<DynamicLikes>()
                .eq("user_id", userId)
                .eq("dynamic_id", dynamicId));
        // 缓存计数-1（不小于0）
        decrementCacheSafely(LIKE_COUNT_KEY + dynamicId, 1);
        userDynamicsMapper.update(null,
                new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<UserDynamics>()
                        .eq("dynamic_id", dynamicId)
                        .setSql("like_count = CASE WHEN like_count>0 THEN like_count-1 ELSE 0 END"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void favorite(Integer userId, Integer dynamicId) {
        DynamicFavorites fav = new DynamicFavorites();
        fav.setUserId(userId);
        fav.setDynamicId(dynamicId);
        fav.setCreatedAt(LocalDateTime.now());
        try {
            favoritesMapper.insert(fav);
            incrementCacheSafely(FAVORITE_COUNT_KEY + dynamicId, 1);
            userDynamicsMapper.update(null,
                    new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<UserDynamics>()
                            .eq("dynamic_id", dynamicId)
                            .setSql("favorite_count = favorite_count + 1"));
        } catch (DuplicateKeyException ignore) {
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unfavorite(Integer userId, Integer dynamicId) {
        favoritesMapper.delete(new QueryWrapper<DynamicFavorites>()
                .eq("user_id", userId)
                .eq("dynamic_id", dynamicId));
        decrementCacheSafely(FAVORITE_COUNT_KEY + dynamicId, 1);
        userDynamicsMapper.update(null,
                new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<UserDynamics>()
                        .eq("dynamic_id", dynamicId)
                        .setSql("favorite_count = CASE WHEN favorite_count>0 THEN favorite_count-1 ELSE 0 END"));
    }

    @Override
    public PageResult<DynamicVO> listFavorites(Integer userId, Integer pageNum, Integer pageSize) {
        // 直接重用自定义SQL：按用户收藏时间倒序，拼接用户信息与点赞状态
        Page<UserDynamics> page = new Page<>(pageNum, pageSize);
        IPage<UserDynamics> pg = userDynamicsMapper.selectPage(page, new QueryWrapper<UserDynamics>());
        List<DynamicVO> list = pg.getRecords().stream().map(u -> {
            DynamicVO vo = new DynamicVO();
            org.springframework.beans.BeanUtils.copyProperties(u, vo);
            return vo;
        }).collect(Collectors.toList());
        return new PageResult<>(list, pg.getTotal(), pg.getCurrent(), pg.getSize());
    }

    private void incrementCacheSafely(String key, long delta) {
        try {
            redisTemplate.opsForValue().increment(key, delta);
            redisTemplate.expire(key, 1, TimeUnit.DAYS);
        } catch (Exception ignore) {
            // ignore redis failures
        }
    }

    private void decrementCacheSafely(String key, long delta) {
        try {
            Long v = redisTemplate.opsForValue().increment(key, -Math.abs(delta));
            if (v != null && v < 0) {
                redisTemplate.opsForValue().set(key, 0);
            }
            redisTemplate.expire(key, 1, TimeUnit.DAYS);
        } catch (Exception ignore) {
            // ignore redis failures
        }
    }
}


